<%@page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8" %>

<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@taglib prefix="shiro" uri="http://shiro.apache.org/tags"%>

<!doctype html>

<html>
    <head>
        <title>React实战入门-初体验</title>

        <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.2.1/react.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.2.1/react-dom.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/prop-types/15.6.2/prop-types.min.js"></script>

        <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.1.1/css/bootstrap.min.css"/>
    </head>
    <body>
        <div class="container">
            <div id="root" style="padding-top:30px;">

            </div>
        </div>

        <script type="text/babel">
            class App extends React.Component { //定义组件，组件名为App，组件首字母大写
                constructor(props) {//构造函数。其中，props主要用于实现数据与方法的共享，接收组件中传递过来的属性信息（HashMap，可以是数据，也可以是方法），使用方式为this.props，只读不可修改。如要实现组建内部的数据（即状态，state）的存储与共享，应使用this.state
                    super(props);
                    this.state = {
                        users: [] //设置数据初始值
                    };
                }

                /**
                 * 约定方法，生命周期，组件加载结束时调用，简单理解，render之后调用（componentWillMount, componentDidMount, componentWillReceiveProps, componentWillUpdate, componentDidUpdate, componentWillUnmount）
                 */
                componentDidMount = () => {
                    console.log("组件加载（结束）--->componentDidMount");
                    this.loadUsersFromServer();
                }

                /**
                 * 约定方法，部分其他生命周期展示
                 */
                componentWillMount = () => {
                    console.log("组件加载（开始）--->componentWillMount");
                }
                componentWillUpdate = () => {
                    console.log("组件更新（开始）--->componentWillUpdate");
                }
                componentDidUpdate = () => {
                    console.log("组件更新（结束）--->componentDidUpdate");
                }

                //自定义普通方法，从数据库中读取用户列表
                loadUsersFromServer = () => {
                    fetch('/user/index').then((response) => {
                        return response.json(); //此返回值将传给下一个then的参数（data）,简单理解，等同于JSON.parse(response.text())
                    }).then((data) => {
                        console.log("用户列表(users)：");
                        console.log(data);

                        this.setState({
                            users: data //设置状态同时更新dom
                        });
                    });
                }

                // 自定义普通方法，创建用户。当前写法的好处是：不用绑定this（this.createUser = this.createUser.bind(this);）
                createUser = (user) => {
                    fetch('/user/save', {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json'
                        },
                        body: JSON.stringify(user)
                    }).then((response) => {
                        this.loadUsersFromServer();
                    })
                }

                // 自定义普通方法，删除用户
                deleteUser = (user) => {
                    console.log(user.id);
                    let data = new FormData()
                    data.append("id", user.id)

                    fetch ("/user/delete", {
                        method: 'POST',
                        body:data
                    }).then((response) => {
                        this.loadUsersFromServer();
                    })
                }

                render() {
                    return (
                        <div>
                            <UserForm createUser={this.createUser}/> {/*把创建方法传到子组件里*/}
                            <br/>
                            <UserTable deleteUser={this.deleteUser} users={this.state.users}/> {/*把删除方法传到子组件里，同时传入的还有用户列表*/}
                        </div>
                    );
                }
            }

            class UserForm extends React.Component { //表单，用于创建用户
                constructor(props) {
                    super(props);

                    console.log("表单默认值(defaultProps)：");
                    console.log(props);

                    this.state = {username: props.username, password: props.password, realname: props.realname}; //传入默认值
                }

                //定义props默认值
                static defaultProps = {
                    username: 'lvchanglong',
                    password: '123456',
                    realname: '吕常龙'
                }

                //自定义事件处理方法，建议命名时，以handle开头
                handleChange = (event) => {
                    console.log("NAME: " + event.target.name + " VALUE: " + event.target.value)
                    this.setState(
                        {[event.target.name]: event.target.value} //设置用户信息
                    );
                }

                //自定义事件处理方法
                handleSubmit = (event) => {
                    event.preventDefault(); //阻止默认事件
                    console.log("提交: " + this.state.username + "-" + this.state.password + "-" + this.state.realname);

                    const {username, password, realname} = this.state; //简单理解，批量定义
                    console.log("扩展: " + username + "-" + password + "-" + realname);

                    let newUser = {'username': this.state.username, "password": this.state.password, realname: this.state.realname}; //收集新用户信息
                    this.props.createUser(newUser); //创建新用户
                }

                render() {
                    return (
                        <div className="panel panel-default">
                            <div className="panel-body">
                                <form className="form-inline">
                                    <div className="col-md-3">
                                        <input type="text" placeholder="账号" className="form-control"  name="username" onChange={this.handleChange}/>
                                    </div>
                                    <div className="col-md-3">
                                        <input type="text" placeholder="密码" className="form-control" name="password" onChange={this.handleChange}/>
                                    </div>
                                    <div className="col-md-3">
                                        <input type="text" placeholder="姓名" className="form-control" name="realname" onChange={this.handleChange}/>
                                    </div>
                                    <div className="col-md-3">
                                        <button className="btn btn-success" onClick={this.handleSubmit}>保存</button>
                                    </div>
                                </form>
                            </div>
                        </div>
                    );
                }
            }

            class UserTable extends React.Component {
                constructor(props) {
                    super(props);
                }

                render() {
                    let users = this.props.users.map(user => //数据渲染，把普通数据转化映射成拥有指定格式的数据
                        <User key={user.id} deleteUser={this.props.deleteUser} user={user}/> //传入删除方法，同时传入用户
                    );

                    return (
                        <div>
                            <table className="table table-striped">
                                <thead>
                                    <tr>
                                        <th>账号</th><th>密码</th><th>姓名</th><th>操作</th>
                                    </tr>
                                </thead>
                                <tbody>
                                    {users}
                                </tbody>
                            </table>
                        </div>
                    );
                }
            }

            class User extends React.Component {
                constructor(props) {
                    super(props);
                }

                //自定义事件处理方法
                handleDelete = (event) => {
                    this.props.deleteUser(this.props.user); //删除此用户
                }

                render() {
                    return (
                        <tr>
                            <td>{this.props.user.username}</td>
                            <td>{this.props.user.password}</td>
                            <td>{this.props.user.realname}</td>
                            <td>
                                <button className="btn btn-danger" onClick={this.handleDelete}>删除</button>
                            </td>
                        </tr>
                    );
                }
            }

            ReactDOM.render(<App />, document.getElementById('root'));

            /*function Welcome(props) {
                return (
                    <h1>Hello&nbsp;{props.username}</h1>
                );
            }
            ReactDOM.render(<Welcome username="World"/>, document.getElementById('root'));*/
        </script>
    </body>
</html>
